package com.stone.serviceimpl;

import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import com.stone.dao.IProviderDao;
import com.stone.model.Admin;
import com.stone.model.Provider;
import com.stone.service.IProviderService;
import com.stone.utils.Page;

public class ProviderService implements IProviderService {
	private IProviderDao providerDao;
	private final String INDEXPATH ="\\provider_index";
	private Analyzer analyzer = new StandardAnalyzer();
	// ------------------set and get
	public IProviderDao getProviderDao() {
		return providerDao;
	}

	public void setProviderDao(IProviderDao providerDao) {
		this.providerDao = providerDao;
	}

	//----------------具体的方法实现
	public Provider findProviderById(Long providerId) {
		return providerDao.findById(providerId);
	}
	public Provider addProvider(Provider provider) {
		return providerDao.save(provider);
	}

	public void updateProvider(Provider provider) {
		providerDao.update(provider);
	}

	public Page findAllProviders(int pageNo, int pageSize) {
		return providerDao.findAllProviders(pageNo, pageSize);
	}
	
	public List<Provider> findAllProviders()
	{
		return providerDao.findAll();
	}

	public Page findAllDisplayProviders(int pageNo, int pageSize)
	{
		return providerDao.findAllDisplayProviders(pageNo, pageSize);
	}
	
	public Page getHighSearchProvider(String path,String query, int pageno, int pageSize) {
		try{
			List<Provider> qlist = new ArrayList<Provider>();
//			String fieldName = "title";
			//System.out.println(path+INDEXPATH);
			IndexSearcher indexSearcher = new IndexSearcher(path+INDEXPATH);
			//QueryParser parser = new QueryParser(fieldName, analyzer); //单 key 搜索
			//Query queryOBJ = parser.parse(query);
		//	System.out.println(">>> 2.开始读取索引... ... 通过关键字：【 "+ query +" 】");
			long begin = new Date().getTime();
			//下面的是进行title,content 两个范围内进行收索.
			BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD};
			Query queryOBJ = MultiFieldQueryParser.parse(query, new String[]{"name","address","shortdescription"}, clauses, new StandardAnalyzer());//parser.parse(query);
			Filter filter = null;
			//################# 搜索相似度最高的记录 ###################
			TopDocs topDocs = indexSearcher.search(queryOBJ, filter,100);
			int totalHits = topDocs.totalHits;
			//TopDocs topDocs = indexSearcher.search(queryOBJ , 10000);
		//	System.out.println("*** 共匹配：" + totalHits + "个 ***");
			Page page = new Page(totalHits,pageSize);
			Provider provider = null;
			int startResult = (pageno-1)*pageSize;
			int endResult = (startResult+pageSize)<totalHits?(startResult+pageSize):totalHits;
			ScoreDoc scoreDoc[] = topDocs.scoreDocs;
			//输出结果
			page.setTotalRows(0);
			for(int i=startResult; i<endResult; i++){
//			for (ScoreDoc scoreDoc : topDocs.scoreDocs){
					Document targetDoc = indexSearcher.doc(scoreDoc[i].doc);
					provider = new Provider();
					//设置高亮显示格式
					SimpleHTMLFormatter simpleHTMLFormatter =  new SimpleHTMLFormatter("<font class='red'>", "</font>"); 
					/* 语法高亮显示设置 */
					Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(queryOBJ)); 
					highlighter.setTextFragmenter(new SimpleFragmenter(100)); 
					
					// 设置高亮 设置 title,content 字段
					String name = targetDoc.get("name");
					String desc = targetDoc.get("shortdescription");
					String address = targetDoc.get("address");
					TokenStream nameTokenStream = analyzer.tokenStream("name",new StringReader(name));
					TokenStream descTokenStream = analyzer.tokenStream("shortdescription",new StringReader(desc));
					TokenStream addressTokenStream = analyzer.tokenStream("address",new StringReader(address));
					String  highLightName = highlighter.getBestFragment(nameTokenStream, name);
					String  highLightAddress = highlighter.getBestFragment(addressTokenStream, address);
					String highLightDesc = highlighter.getBestFragment(descTokenStream, desc);
					
				     if(highLightName == null)
				    	 highLightName = name;
				     if(highLightDesc == null) 
				    	 highLightDesc = desc;
				     if(highLightAddress == null) 
				    	 highLightAddress = address;
				     provider.setId(Long.parseLong(targetDoc.get("p_id")));
				     provider.setPhoto(targetDoc.get("photo"));
				     provider.setName(highLightName);
				     provider.setAddress(highLightAddress);
				     provider.setShortDescription(highLightDesc);
				     
				     
				     Provider tempProvider = this.findProviderById(provider.getId());
				     if(tempProvider.getDisplayFlag() != null)
				     {
				     	if(!tempProvider.getDisplayFlag().equals(new Integer(0)))
				     	{
				     		qlist.add(provider);
				     		page.setTotalRows(page.getTotalRows() + 1);
				     	}
				     	System.out.println(tempProvider.getDisplayFlag());
				     }
				     else
				     {
				    	 System.out.println("null");
				    	 qlist.add(provider);
				     }
				     //qlist.add(provider);
			}
			
			long end = new Date().getTime();
		//	System.out.println(">>> 3.搜索完毕... ... 共花费：" + (end - begin) +"毫秒...");
			indexSearcher.close();
			page.setList(qlist);
			page.setCurrentPage(pageno);
			return page;
			}catch(Exception e){
				e.printStackTrace();
				return null;
			}
	}
	/**
	 * 
	 */
	public boolean createIndex(String path){
		//检查索引是否存在
		if(this.isIndexExisted(path))
			return this.isIndexExisted(path);
		return createNewIndex(path);
	}
	public boolean createNewIndex(String path){
		List<Provider> list = providerDao.findAll();
		try
		{
			Directory directory = FSDirectory.getDirectory(path+INDEXPATH);
			IndexWriter indexWriter = new IndexWriter(directory, analyzer ,true, IndexWriter.MaxFieldLength.LIMITED);
			long begin = new Date().getTime();
			for(Provider provider: list)
			{
				Document doc = new Document();
				String name = provider.getName() == null ? "" : provider.getName().trim();
				String address = provider.getAddress() == null ? "" : provider.getAddress().trim();
				String desc = provider.getShortDescription() == null ? "" : provider.getShortDescription().trim();
				String photo = provider.getPhoto() == null ? "" : provider.getPhoto().trim();
				doc.add(new Field("p_id", provider.getId().toString(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
				doc.add(new Field("photo", photo, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
				doc.add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
				doc.add(new Field("address", address, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
				doc.add(new Field("shortdescription", desc, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
				indexWriter.addDocument(doc);
			}
			long end = new Date().getTime();
		//	System.out.println(">>> 1.存入索引完毕.. 共花费：" + (end - begin) +"毫秒...");
			indexWriter.optimize();
			indexWriter.close();
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * check Index is Existed
	 * @return true or false
	 */
	private boolean isIndexExisted(String path)
	{
		try
		{
			File dir = new File(path+INDEXPATH);
			if(dir.listFiles()!=null&&dir.listFiles().length>0)
				return true;
			else
				return false;
			
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
	
	public void deleteProvider(Provider	provider) {
		providerDao.delete(provider);
		
	}

	public List<Provider> findProviderByName(String providerName) {
		return providerDao.findByProperty("name", providerName);
	}

	public Page findProviderByName(String providerName, int pageNo, int pageSize) {
		
		return providerDao.findProviderByName(providerName, pageNo, pageSize);
	}
	
	public boolean check(String userName, String password) {
		List<Provider> list = providerDao.findByProperty("username", userName);
		if(list.size() == 0){
			return false;
		}else{
			Provider provider = list.get(0);
			if(provider.getPassword().equals(password)){
				return true;
			}
		}
		return false;
	}


	public Provider findProviderByUsername(String username) {
		List<Provider> list = providerDao.findByProperty("username", username);
		if(list.size() == 0){
			return null;
		}else{
			return list.get(0);
		}
	}
}
